# -*- coding: utf-8 -*-
"""
数据库重复检测器
负责检测“虚拟视频”与数据库之间的重复项，并提供详细对比
"""
import os
import sys
from typing import List, Dict, Any

from .video_group import VideoGroup

current_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(current_dir)
if project_root not in sys.path:
    sys.path.insert(0, project_root)

from .models import VideoInfo
from .parser import VideoNameParser
from .database import VideoDatabase

try:
    from utils.file_handler import FileHandler
except ImportError:
    from ..utils.file_handler import FileHandler


class DatabaseDuplicateDetector:
    """数据库重复检测器"""

    def __init__(self, db_path: str = "duplicate_checker.db"):
        self.parser = VideoNameParser()
        self.database = VideoDatabase(db_path)

    def check_against_database(self, filenames: List[str], insert_new: bool = False) -> Dict[str, Any]:
        """
        检查文件列表与数据库的重复情况，提供详细对比
        
        :param filenames: 原始文件名列表
        :param insert_new: 是否插入新的不重复文件到数据库
        :return: 检测结果字典
        """
        parsed_videos = [self.parser.parse(filename) for filename in filenames]
        clean_videos = [v for v in parsed_videos if not v.is_dirty]
        dirty_videos = [v for v in parsed_videos if v.is_dirty]

        video_groups = self._group_by_base_id(clean_videos)

        # 检查文件内部是否有版本冲突 (例如，同时有 ADN-001.mp4 和 ADN-001-C.mp4)
        internal_duplicates = {base_id: group for base_id, group in video_groups.items() if group.has_duplicates}
        if internal_duplicates:
            print("文件内部存在重复番号")
            for item in internal_duplicates:
                print(item)
            raise Exception(f"文件内部存在重复番号")

        # 将每个组整合成一个“虚拟视频”对象
        consolidated_videos = [self._consolidate_video_group(group) for group in video_groups.values()]

        comparison_results = []
        new_videos_to_insert = []

        for local_video in consolidated_videos:
            db_video = self.database.get_by_core_id(local_video.clean_core_id)
            if db_video:
                comparison_results.append({
                    'core_id': local_video.clean_core_id,
                    'local_video': local_video,
                    'db_video': db_video
                })
            else:
                new_videos_to_insert.append(local_video)

        insert_success_count = 0
        insert_failed_ids = []
        if insert_new and new_videos_to_insert:
            insert_success_count, insert_failed_ids = self.database.batch_insert_videos(new_videos_to_insert)

        return {
            'total_files': len(filenames),
            'clean_files': len(clean_videos),
            'dirty_files': len(dirty_videos),
            'comparison_results': comparison_results,
            'new_videos': new_videos_to_insert,
            'insert_enabled': insert_new,
            'insert_success': insert_success_count,
            'insert_failed': len(insert_failed_ids),
            'dirty_data': dirty_videos,
        }

    def _consolidate_video_group(self, group: VideoGroup) -> VideoInfo:
        """将一个VideoGroup整合成一个代表整体的VideoInfo对象"""
        all_files = group.get_all_files()
        template_video = all_files[0]

        has_subtitle = any(v.has_subtitle for v in all_files)
        has_leak = any(v.has_leak for v in all_files)
        has_4k = any(v.has_4k for v in all_files)

        segment_files = [v for v in all_files if v.is_segment]
        segment_count = len(segment_files)

        if segment_count == 0 and len(all_files) > 0:
            segment_count = 1

        return VideoInfo(
            original_filename=group.base_id,
            core_id=group.base_id,
            video_type=template_video.video_type,
            video_subtype=template_video.video_subtype,
            prefix=template_video.prefix,
            number=template_video.number,
            extension=".mkv",
            has_subtitle=has_subtitle,
            has_leak=has_leak,
            has_4k=has_4k,
            segment_count=segment_count
        )

    def _group_by_base_id(self, videos: List[VideoInfo]) -> Dict[str, VideoGroup]:
        """按基础番号分组视频"""
        video_groups = {}
        for video in videos:
            base_id = video.clean_core_id
            if base_id not in video_groups:
                video_groups[base_id] = VideoGroup(base_id=base_id, video_type=video.video_type)
            video_groups[base_id].add_video(video)
        return video_groups

    def get_database_statistics(self) -> dict:
        return self.database.get_statistics()

    def find_missing_numbers(self, prefix: str, max_number: int) -> List[str]:
        existing_numbers = self.database.get_numbers_by_prefix(prefix)
        expected_numbers = set(range(1, max_number + 1))
        missing_numbers = expected_numbers - set(existing_numbers)
        zero_pad_width = len(str(max_number))

        missing_list = []
        for num in sorted(missing_numbers):
            formatted_number = f"{num:0{zero_pad_width}d}"
            missing_list.append(f"{prefix.upper()}-{formatted_number}")
        return missing_list

    def import_file_to_database(self, filename: str) -> Dict[str, Any]:
        file_handler = FileHandler()
        filenames = file_handler.read_file_list(filename)
        if not filenames:
            return {'success': False, 'error': '文件为空或读取失败'}

        result = self.check_against_database(filenames, insert_new=True)
        return {
            'success': True,
            'total_processed': result['total_files'],
            'imported_count': result['insert_success'],
            'failed_count': result['insert_failed'],
            'existing_count': len(result['comparison_results']),
            'dirty_count': result['dirty_files'],
        }

    def close(self):
        self.database.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
